#include <stdint.h>

#include "plf.h"
#include "driver_iic.h"
#include "driver_gpio.h"
#include "driver_system.h"
#include "driver_exti.h"

#define TOUCHPAD_IIC_SLAVE_ADDRESS          0x15

static void touchpad_init_pin(void)
{
    system_set_port_mux(GPIO_PORT_B, GPIO_BIT_6, PORTB6_FUNC_I2C1_CLK);
    system_set_port_mux(GPIO_PORT_B, GPIO_BIT_7, PORTB7_FUNC_I2C1_DAT);

    system_set_port_mux(GPIO_PORT_A, GPIO_BIT_6, PORTA6_FUNC_A6);
    system_set_port_mux(GPIO_PORT_A, GPIO_BIT_7, PORTA7_FUNC_A7);
    gpio_set_dir(GPIO_PORT_A, GPIO_BIT_6, GPIO_DIR_OUT);    // reset
    gpio_set_dir(GPIO_PORT_A, GPIO_BIT_7, GPIO_DIR_IN);     // int
    gpio_set_func(GPIO_PORT_A, GPIO_BIT_7, GPIO_FUNC_EXTI);
}

static void touchpad_init_iic(void)
{
    struct i2c_config_param_t config_param;

    config_param.channel = I2C_CHANNEL_1;
    config_param.speed = I2C_SPEED_STANDARD;
    config_param.work_role = I2C_WORK_ROLE_MASTER;
    i2c_init(&config_param);
}

static void touchpad_init_int(void)
{
    exti_set_type(EXTI_GPIOA_7, EXTI_TYPE_NEG);
    exti_set_control(EXTI_GPIOA_7, 500000, 2);
    exti_enable(GPIO_PA7);
}

void touchpad_read_data(void)
{
#define READ_SIZE       8
    struct i2c_receive_param_t receive_param;
    uint8_t rx_buffer[READ_SIZE];
    
    receive_param.channel = I2C_CHANNEL_1;
    receive_param.addr_type = I2C_ADDR_MODE_7b;
    receive_param.slave_addr = TOUCHPAD_IIC_SLAVE_ADDRESS;
    receive_param.reg_length = 1;
    receive_param.reg = 0x00;
    receive_param.length = READ_SIZE;
    receive_param.buffer = rx_buffer;
    i2c_receive(&receive_param);
}

void touchpad_init(void)
{
    touchpad_init_pin();
    touchpad_init_iic();

    /* reset touch pad chip */
    gpio_porta_write(gpio_porta_read() | 0x40);
    co_delay_100us(100);
    gpio_porta_write(gpio_porta_read() & 0xbf);
    co_delay_100us(50);
    gpio_porta_write(gpio_porta_read() | 0x40);
    co_delay_100us(2000);

    touchpad_init_int();
    NVIC_EnableIRQ(GPIO_IRQn);
}

void exti_isr_ram(void)
{
    uint32_t status;
    
    status = exti_get_status();
    exti_clear(status);

    touchpad_read_data();
}

